package eu.liquify.ui {
	import flash.display.Graphics;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.FocusEvent;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFieldType;
	import flash.text.TextFormat;
	import flash.text.TextFormatAlign;
	import flash.ui.Keyboard;
	import flash.ui.Mouse;
	import flash.ui.MouseCursor;
	public class TextInput extends UIItem implements IHasBindValue {
		public static const TEXT_UPDATE:String = "textUpdate";
		
		public var change:Function = NULL_FUNCTION;
		
		
		private var defaultText:String = "";
		
		private var _readonly:Boolean;
		
		private var _centered:Boolean = false;
		
		private var backgroundDisplay:Sprite = new Sprite();
		protected var txt:TextField = new TextField();
		
		private var border:int = -1;
		private var background:int = -1;
		
		private var normalFormat:TextFormat = new TextFormat("Tahoma", 9, null, true, null, null, null, null, TextFormatAlign.LEFT);
		private var readonlyFormat:TextFormat = new TextFormat("Tahoma", 9, null, true, null, null, null, null, TextFormatAlign.LEFT);
		
		public function TextInput(options:Object = null) {
			backgroundDisplay.useHandCursor = false;
			addChild(backgroundDisplay);
			
			txt.defaultTextFormat = normalFormat;
			txt.text = defaultText;
			txt.height = 15;
			txt.type = TextFieldType.INPUT;
			//txt.addEventListener(FocusEvent.FOCUS_OUT, focusOut, false, 0, true);
			txt.addEventListener(FocusEvent.KEY_FOCUS_CHANGE, focusChange, false, 0, true);
			txt.addEventListener(FocusEvent.MOUSE_FOCUS_CHANGE, focusChange, false, 0, true);
			txt.addEventListener(KeyboardEvent.KEY_DOWN, keyDown, false, 0, true);
			txt.tabIndex = nextTabIndex++;
			//txt.background = true;
			//txt.backgroundColor = 0xFBAAF4;
			addChild(txt);
			
			super();
			readonly = false;
			applyOptions(options);
		}
		
		override public function resize():void {
			super.resize();
			
			if (fixedSize) {
				txt.autoSize = TextFieldAutoSize.NONE;
				txt.width = width;
				txt.height = height = txt.textHeight+4;
			} else {
				txt.autoSize = TextFieldAutoSize.LEFT;
			}
			txt.y = height/2-txt.height/2;
			
			updateCenter();
			
			redraw();
		}
		
		public function get bindValue():Object { return text; }
		public function set bindValue(v:Object):void { text = String(v); }
		
		public function get centered():Boolean {
			return _centered;
		}
		
		public function set centered(value:Boolean):void {
			_centered = value;
			if (value) {
				txt.addEventListener(Event.CHANGE, updateCenter, false, 0, true);
				backgroundDisplay.buttonMode = true;
				backgroundDisplay.addEventListener(MouseEvent.MOUSE_OVER, backgroundOver, false, 0, true);
				backgroundDisplay.addEventListener(MouseEvent.MOUSE_OUT, backgroundOut, false, 0, true);
				backgroundDisplay.addEventListener(MouseEvent.MOUSE_DOWN, backgroundDown, false, 0, true);
			} else {
				txt.removeEventListener(Event.CHANGE, updateCenter);
				backgroundDisplay.buttonMode = false;
				backgroundDisplay.removeEventListener(MouseEvent.MOUSE_DOWN, backgroundDown);
				backgroundDisplay.removeEventListener(MouseEvent.MOUSE_OVER, backgroundOver);
				backgroundDisplay.removeEventListener(MouseEvent.MOUSE_OUT, backgroundOut);
				backgroundOut();
			}
			updateCenter();
		}
		
		private function backgroundOver(e:MouseEvent):void {
			Mouse.cursor = MouseCursor.IBEAM;
		}
		private function backgroundOut(e:MouseEvent = null):void {
			Mouse.cursor = MouseCursor.AUTO;
		}
		
		private function backgroundDown(e:MouseEvent):void {
			stage.focus = txt;
			if (backgroundDisplay.mouseX > txt.x+txt.width/2) {
				txt.setSelection(txt.length, txt.length);
			} else {
				txt.setSelection(0, 0);
			}
		}
		
		private function updateCenter(e:Event = null):void {
			var txtWidth:Number = txt.textWidth+6;
			if (centered && txtWidth < width) {
				txt.x = Math.round(width/2-txtWidth/2);
				if (fixedSize) {
					txt.scrollH = 0;
					txt.width = txtWidth;
				}
			} else {
				txt.x = 0;
				if (fixedSize) txt.width = width;
			}
		}
		
		private function redraw():void {
			var g:Graphics = backgroundDisplay.graphics;
			g.clear();
			if (border > -1) {
				g.lineStyle(0, border);
			}
			if (background > -1) {
				g.beginFill(background);
			}
			g.drawRect(0, 0, width, height);
		}
		
		public function get readonly():Boolean {
			return _readonly;
		}
		
		public function set readonly(value:Boolean):void {
			_readonly = value;
			if (readonly) {
				txt.defaultTextFormat = readonlyFormat;
				//txt.border = false;
				//txt.background = false;
				border = background = -1;
				txt.selectable = txt.mouseEnabled = txt.tabEnabled = false;
			} else {
				txt.defaultTextFormat = normalFormat;
				//txt.border = true;
				//txt.borderColor = 0xDBDBDB;
				//txt.background = true;
				//txt.backgroundColor = 0xEFEFEF;
				border = 0xDBDBDB;
				background = 0xEFEFEF;
				txt.selectable = txt.mouseEnabled = txt.tabEnabled = true;
			}
			redraw();
		}
		
		public function get text():String {
			return txt.text;
		}
		public function set text(v:String):void {
			txt.text = v;
			resize();
		}	
		public function get backgroundColor():uint {
			return txt.backgroundColor;
		}
		public function set backgroundColor(v:uint):void {
			txt.backgroundColor = v;
		}
		
		private function keyDown(e:KeyboardEvent):void {
			if (e.keyCode == Keyboard.ENTER) updateChange();
		}
		private function focusChange(e:FocusEvent):void {
			if (e.relatedObject != backgroundDisplay) updateChange();
		}
		protected function updateChange():void {
			dispatchEvent(new Event(TEXT_UPDATE));
			Utils.callDynamic(change, this);
		}
	}
}